
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;


public abstract class Rectangle {

	public BufferedImage bi=null;
	/**
	 * linke obere Ecke des Rechtecks x-Koordinate
	 */
	public int x;
	/**
	 * y-Koordinate der linken oberen Ecke des Rechtecks
	 */
	public int y;
	
	/**
	 * Seitenlaenge des Rechtecks(Quadrats)
	 */
	public int size;
	
	/**
	 * HIlfsvariablen fuer x+s, y+s
	 */
	public int x2,y2;
	
	/**
	 * Konstruktor der neues Rectangle aus einem Point und der Seitenlaenge erzeugt
	 * @param p Mittelpunkt des Rectangles
	 * @param s Seitenlaenge
	 */
	public Rectangle(Point p,int s){
		this.x=p.x-s/2;
		this.y=p.y-s/2;
		this.size=s;
		
		this.x2=p.x+s/2;
		this.y2=p.y+s/2;
	}//constructor

	/**
	 * Copy-Konstruktor der neues Rectangle nach Uebergabe eines anderen erzeugt
	 * @param r Rectangle des Eigenschaften uebernommen werden sollen
	 */
	public Rectangle(Rectangle r){
		this.x=r.x;
		this.y=r.y;
		this.size=r.size;
		
		this.x2=r.x2;
		this.y2=r.y2;
	}
	
	/**
	 * Konstruktor der neues Rectangle aus Punktkoordinaten und der Seitenlaenge erzeugt
	 * @param x x-Koordinate des Mittelpunktes
	 * @param y y-Koordinate des Mittelpunktes
	 * @param s Seitenlaenge des Rechtecks
	 */
	public Rectangle(int x, int y, int s){
		this.x=x-s/2;
		this.y=y-s/2;
		this.size=s;
		
		this.x2=x+s/2;
		this.y2=y+s/2;
	}
	
	/**
	 * setzt ein Rectangle um
	 * @param p neuer Mittelpunkt
	 */
	public void setPosition(Point p){
		this.x=p.x-size/2;
		this.y=p.y-size/2;
		this.x2=x+size;
		this.y2=y+size;
		//this.x
	}
	

 	/**
 	 * gibt die obere linke Ecke des Rectangles als Point zurueck
 	 * @return Point 
 	 */
	public Point getPosition(){
		return new Point(x,y);
	}
	
	/*
	 * other Methods
	 */
	
	/**
	 * gibt den Mittelpunkt zurueck
	 */
	public Point getMidPoint(){
		return new Point(x+(size/2),y+(size/2));
	}
	
	/**
	 * gibt die x-Koordinate des Mittelpunktes zurueck
	 * @return x-Koordinate
	 */
	public int getMidPointX(){
		return (x+size/2);
	}
	
	/**
	 * gibt die y-Koordinate des Mittelpunktes zurueck
	 * @return y-Koordinate
	 */
	public int getMidPointY(){
		return (y+size/2);
	}
	
	/**
	 * zeichnet ein gefuelltes Rechteck entsprechend den Rectangle_Dimensionen auf ein
	 * Graphics Object
	 * @param g Graphics Object auf das geziechnet wird
	 */
	public void drawPreviewPosition(Graphics g){
		g.fillRect(x,y, size, size);
	}
		
	public void resize(int newSize){
		this.size=newSize;
		x2=x+newSize;
		y2=y+newSize;
	}
	
	/**
	 * ueberprueft ob sich das aktuelle Rechteck und ein weiteres
	 * sich ueberschneiden bzw ineinanderliegen
	 * @param rect zuschneidendes Rechteck 
	 * @return true, wenn sich die beiden Rechtecke ueberschneiden
	 */
	public boolean interlapse(Rectangle rect){
	 
		return (isInRect(rect.x, rect.y)
				|| isInRect(rect.x+rect.size,rect.y)
				|| isInRect(rect.x, rect.y+rect.size)
				|| isInRect(rect.x+rect.size, rect.y+rect.size));
	}
	
	/**
	 * Funktion die ueberprueft ob die uebergebenen Koordinaten eines Punktes innerhalb des
	 * Rectangles liegen
	 * @param a x-Koordinate
	 * @param b y-Koordinate
	 * @return true, wenn Punkt im Rechteck liegt
	 */
	public boolean isInRect(int a, int b){
		if(a >=this.x && a <=x+size
				&& b >=this.y && b<=y+size){
			return true;
		}
		return false;
	}
	
	/**
	 * Ueberprueft ob sich das Rechteck ausserhlab einer gegebenen Box befindet
	 * @param w Breite der Testboc
	 * @param h Hoehe der Testbox
	 * @return true, wenn sich das Rechteck ausserhalb dieser Box befindet
	 */
	public boolean isOutOfBounds(int w, int h){
		if(this.x<0 || x+size > w || y<0 || y+size>h){
			return true;
		}
		return false;
		
	}//isOutOfBounds(int w, int h)
	

	/**
	 * testet ob ein Punkt auf dem Rand eines Rechteckes liegt
	 * @param a x-Koordinate eines Punktes
	 * @param b y-KOordinate eines Punktes
	 * @return true, wenn uebergebener Punkt auf der Grenze des Rechtecks liegt
	 */
	public boolean isAtBorder(int a, int b){
		if((a>=this.x && a<=this.x+size)&&
				b>=this.y && b<this.y+size){
			return true;
		}
		return false;
	}
}//class
